const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null)
const deepClone = function(obj, hash = new WeakMap()) {
	if (obj.constructor === Date)
		return new Date(obj) // 日期对象直接返回一个新的日期对象
	if (obj.constructor === RegExp)
		return new RegExp(obj) //正则对象直接返回一个新的正则对象
	//如果循环引用了就用 weakMap 来解决
	if (hash.has(obj)) return hash.get(obj)
	let allDesc = Object.getOwnPropertyDescriptors(obj)
	//遍历传入参数所有键的特性
	let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
	//继承原型链
	hash.set(obj, cloneObj)
	for (let key of Reflect.ownKeys(obj)) {
		cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key],
			hash) : obj[key]
	}
	return cloneObj
}
function deepClone2(obj, hash = new WeakMap()) {
  if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝
  if (typeof obj !== "object") return obj;
  // 是对象的话就要进行深拷贝
  if (hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
  hash.set(obj, cloneObj);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 实现一个递归拷贝
      cloneObj[key] = deepClone(obj[key], hash);
    }
  }
  return cloneObj;
}

const deepCloneEasy = function(data){
	return JSON.parse(JSON.stringify(data));
}
export {deepClone,deepCloneEasy};
